home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SampleFileTranslationExt.c
-
- Contains: Sample code shell for writing a File Translation Extension.
-
- Copyright: © 1991-1992 by Apple Computer, Inc., all rights reserved.
-
- */
-
-
-
- #include <Resources.h>
- #include <Files.h>
- #include <Errors.h>
- #include "Components.h"
- #include "TranslationExtensions.h"
-
-
-
- /*
- Notes:
-
- Errors:
- All routines return OSErr's. If they succeed they should return noErr.
- The component manager requires all routines to return a ComponentResult
- which is a 32-bit long to simplify dispatching. If your code returns an OSErr
- the compiler will automatically promote it to a long (ComponentResult).
-
- Globals:
- Your routines can not use globals. There really is no reason they should
- need to use globals. The three routines are separate and self contained.
- If you persist and try to use PC relative globals, be warned that the
- ComponentMgr may purge and reload your code resource. Therefore all
- PC relative globals must be preinitailized at compile time (not load time).
- Also, the ComponentMgr routine SetComponentInstanceStorage can not be
- used, because InstanceStorage is already used by the TranslationMgr.
-
- Memory allocation:
- When one of your three routines is called, the default heap is a zone that
- the TranslationMgr allocated. You should do all allocation in that heap.
- Any leaks will be reclaimed when the heap is destroyed when your routine
- returns. WARNING: Do not leave any resource files open. Their maps
- will be left in the heap and trashed. The ResourceMgr will soon croak.
-
- Resources:
- If you need to access resources from your Translation Extension file, you
- will need to use OpenComponentResFile() and CloseComponentResFile().
- The open routine requires the ComponentInstance parameter supplied to
- your routine.
-
- Capabilities:
- There are two kinds of translations: file and scrap. There are three routines
- for each. In order to tell the TranslationMgr which kinds your extension
- supports, you need to set the flags in the 'thng' resource. The bit masks are
- kSupportsFileTranslation and kSupportsScrapTranslation.
-
- */
-
-
-
- /***********************************************************************************************
- *
- * The purpose of DoGetFileTranslationList is to tell the TranslationMgr what file formats
- * this extension can translate between.
- *
- * You are given the list that you built for the TranslationMgr last time, or if this is
- * the first time you've been called, the list if empty (groupCount = 0, modDate = 0).
- *
- * You need to figure out if the file formats we can translate between has changed. For
- * example, the user has installed more translators. One way to check this is to compare
- * the modDate of the list with the modDate of the file/folder of the translators.
- * If it has not changed, you just return without changing the list.
- *
- *
- * Catalog information about your available translators
- *
- * Divide the translators into groups. Within each group, any of the 'src' formats
- * can used with an of the 'dst' formats (any reader can be connected to any writer).
- *
- * Resize the translationList handle to hold all the information about each group.
- * Fill in the translationList.
- *
- * Use the modDate field as a "version" of the list. When you are called again, you can
- * use it to quickly check if the list needs to be rebuilt. The TranslationMgr checks the
- * modDate of the list before and after call you DoGetFileTranslationList. If the modDate
- * has changed, the TranslationMgr updates its internal tables of translation info and saves
- * the new list to disk for use next time that DoGetFileTranslationList is called.
- *
- * The groupCount field is the number of groups in the list.
- * Each group consists of a list of 'src' and 'dst' FileTypeSpec's. Each FileTypeSpec
- * contains the FileType of the file format that will be read or written, a 32-bit hint,
- * translation attributes, and the canonical HFS type and creator.
- * This hint is for use by your File Translation Extension. It is intended to be used to
- * quickly locate the required translator.
- *
- * An example translationList that converts from WriteNow™ to MacWrite™ 5.0 documents would
- * look list this:
- *
- * 0xA5BC1234 ; modDate
- * 1 ; only 1 group
- * 1 ; 1 source type
- * 20 ; size of each entry = sizeof(FileTypeSpec)
- * 'nX^d' ; WriteNow FileType
- * 0 ; hint for WriteNow FileType (0=unused)
- * 0 ; no attributes
- * 'nX^d' ; HFS type of WriteNow documents
- * 'nX^n' ; HFS creator of WriteNow documents
- * 1 ; 1 destination type
- * 20 ; size of each entry = sizeof(FileTypeSpec)
- * 'WORD' ; MacWrite 5.0 FileType
- * 0 ; hint for MacWrite 5.0 FileType (0=unused)
- * 0 ; no attributes
- * 'WORD' ; HFS type of MacWrite 5.0 documents
- * 'MACA' ; HFS creator of MacWrite 5.0 documents
- *
- *
- * If you return an error, the TranslationMgr will ignore your translation list. This will
- * effectively disable your extension from being called. When the machine is restarted,
- * your DoGetFileTranslationList will get called again.
- *
- ************************************************************************************************/
- pascal ComponentResult DoGetFileTranslationList(ComponentInstance self,
- FileTranslationListHandle translationList)
- {
- #pragma unused(self)
- #pragma unused(translationList)
- return noErr;
- }
-
-
-
-
-
-
-
- /***********************************************************************************************
- *
- * The purpose of DoIdentifyFile is to look at the data in a file and determine its FileType.
- *
- * When a file needs to be translated, all installed File Translation Extensions are called
- * to identify the file. If a Translation Extension can identify the file, the translation
- * list for that extension is searched for the FileType as which it recognized the file.
- *
- * Thus, a Translation Extension is guaranteed that DoIdentifyFile will be called to recognize
- * a file before DoTranslateFile is called to convert it.
- *
- * return noTypeErr if you do not recognize the document format.
- *
- ************************************************************************************************/
- pascal ComponentResult DoIdentifyFile(ComponentInstance self, const FSSpec* theDoc, FileType* docKind)
- {
- #pragma unused(self)
- #pragma unused(theDoc)
- #pragma unused(docKind)
- return noTypeErr;
- }
-
-
-
-
- #define progressAdvertismentResID 150
-
- /***********************************************************************************************
- *
- * The purpose of DoTranslateFile is to translate a file from one format to a file of another format.
- *
- * progressRefNum is a refum passed to the progress call back routines.
- * srcDoc is the source document from which to read and translate.
- * srcType is the FileType of the source document as verified by DoIdentifyFile.
- * srcTypeHint is the hint that was paired with srcType in your FileTranslationList.
- * dstDoc is the destination document to which to write the translated file.
- * dstType is the desired FileType of the translated file.
- * dstTypeHint is the hint that was paired with dstType in your FileTranslationList.
- *
- * A note about 'hints'. They are only hints. Your extension must be able to operate without
- * them or if they are incorrect.
- *
- * You can use all the standard File Manager and Memory Manager routines to accomplish the translation.
- *
- * The first thing you should do is call SetTranslationAdvertisement. It will draw the progress
- * dialog window. The PicHandle parameter is a handle to the PICT that will be drawn in
- * in the top of the progress dialog. If it is NIL, no advertisment will be drawn, and the
- * dialog will be shrunk down to eliminate the blank space. Note, this shrinking will also
- * happen if you call UpdateTranslationProgress before SetTranslationAdvertisement. The
- * TranslationMgr will DisposeHandle the PICT when the translation is done. Therefore,
- * the PICT should be a non-purgable, non-resource handle. If you store it as a resource
- * in your Translation Extension, use OpenComponentResFile and DetachResource.
- *
- * You must periodically call the progress "call back" routine UpdateTranslationProgress.
- * You pass to it a number from one to one hundred that represents the chronological
- * percentage of the translation that has been completed.
- * The progress routine updates the progress status bar and handles the events a user can
- * do to cancel the translation. If the user does cancel, that fact is returned to you by the
- * progress routine. You should abort the translation, clean up anything you have allocated
- * and return userCancelErr.
- *
- ************************************************************************************************/
- pascal ComponentResult DoTranslateFile(ComponentInstance self, TranslationRefNum progressRefNum,
- const FSSpec* srcDoc, FileType srcType, long srcTypeHint,
- const FSSpec* dstDoc, FileType dstType, long dstTypeHint)
- {
- #pragma unused(srcDoc)
- #pragma unused(srcType)
- #pragma unused(srcTypeHint)
- #pragma unused(dstDoc)
- #pragma unused(dstType)
- #pragma unused(dstTypeHint)
-
- // first thing to do is display progress dialog and show advertisment
- {
- Handle advert;
- short myResFile;
-
- myResFile = OpenComponentResFile((Component)self);
- if (myResFile != -1)
- {
- advert = GetResource('PICT', progressAdvertismentResID);
- DetachResource(advert);
- SetTranslationAdvertisement(progressRefNum, (PicHandle)advert);
- CloseComponentResFile(myResFile);
- };
- }
-
-
- return invalidTranslationPathErr;
- }
-
-
-
-
-
-
-
- /***********************************************************************************************
- *
- * The purpose of DoGetScrapTranslationList is to tell the TranslationMgr what scrap formats
- * this extension can translate between.
- *
- * You are given the list that you built for the TranslationMgr last time, or if this is
- * the first time you've been called, the list if empty (groupCount = 0, modDate = 0).
- *
- * You need to figure out if the scrap formats you can translate between has changed. For
- * example, the user has installed more translators. One way to check this is to compare
- * the modDate of the list with the modDate of the file/folder of the translators.
- * If it has not changed, you just return without changing the list.
- *
- *
- * Catalog information about your available translators
- *
- * Divide the translators into groups. Within each group, any of the 'src' formats
- * can used with an of the 'dst' formats (any reader can be connected to any writer).
- *
- * Resize the translationList handle to hold all the information about each group.
- * Fill in the translationList.
- *
- * Use the modDate field as a "version" of the list. When you are called again, you can
- * use it to quickly check if the list needs to be rebuilt. The TranslationMgr checks the
- * modDate of the list before and after call you DoGetFileTranslationList. If the modDate
- * has changed, the TranslationMgr updates its internal tables of translation info and saves
- * the new list to disk for use next time that DoGetFileTranslationList is called.
- *
- * The groupCount field is the number of groups in the list.
- * Each group consists of a list of 'src' and 'dst' ScrapTypeSpec's. Each ScrapTypeSpec
- * contains the ScrapType of the format that will be read or written and a 32-bit hint.
- * This hint is for use by your Scrap Translation Extension. It is intended to be used to
- * quickly locate the required translator.
- *
- * An example translationList that converts from MacDrawII scrap to a PICT would
- * look list this:
- *
- * 0xA5BC1234 ; modDate
- * 1 ; only 1 group
- * 8 ; size of each entry = sizeof(ScrapTypeSpec)
- * 1 ; 1 source type
- * 'MDPL' ; MacDrawII ScrapType
- * 0 ; hint for MacDrawII ScrapType (0=unused)
- * 1 ; 1 destination type
- * 8 ; size of each entry = sizeof(ScrapTypeSpec)
- * 'PICT' ; PICT ScrapType
- * 0 ; hint for PICT ScrapType (0=unused)
- *
- *
- * Styled text is handled is a special manner. The problem is that Styled Text requires two
- * formats 'styl' and 'TEXT'. The solution is an intermediate format 'stxt'. It is a 'TEXT'
- * handle concatenated onto the end of a 'styl' handle. A translation extension that converts
- * RTF to styled text would list 'RTF ' as a source format and 'stxt' as a destination format.
- * The Translation Mgr deals with unpacking 'stxt' to get 'styl' or 'TEXT', as needed.
- *
- *
- * If you return an error, the TranslationMgr will ignore your translation list. This will
- * effectively disable your extension from being called. When the machine is restarted,
- * your DoGetFileTranslationList will get called again.
- *
- ************************************************************************************************/
- pascal ComponentResult DoGetScrapTranslationList(ComponentInstance self, ScrapTranslationListHandle list)
- {
- #pragma unused(self)
- #pragma unused(list)
- return paramErr;
- }
-
-
-
- /***********************************************************************************************
- *
- * The purpose of DoIdentifyScrap is to look at the data in a buffer and determine its ScrapType.
- *
- * When data needs to be translated, if an installed Scrap Translation Extensions says it can
- * translate an existing ScrapType into a ScrapType that is required, the Translation Extension
- * is called to verify the format of the data in the buffer.
- *
- * Thus, a Translation Extension is guaranteed that DoIdentifyScrap will be called to recognize
- * data before DoTranslateScrap is called to convert it.
- *
- * return noTypeErr if the data in the buffer is not the format you can translated.
- *
- ************************************************************************************************/
- pascal ComponentResult DoIdentifyScrap(ComponentInstance self, const void* dataPtr, Size dataLength, ScrapType* dataFormat)
- {
- #pragma unused(self)
- #pragma unused(dataPtr)
- #pragma unused(dataLength)
- #pragma unused(dataFormat)
- return paramErr;
- }
-
-
- /***********************************************************************************************
- *
- * The purpose of DoTranslateScrap is to translate a buffer from one format to a buffer of another format.
- *
- * progressRefNum is a refum passed to the progress call back routines.
- * srcDataPtr is a pointer to the source data from which to read and translate.
- * srcDataLength is the length of source data.
- * srcType is the ScrapType of the source document as verified by DoIdentifyScrap.
- * srcTypeHint is the hint that was paired with srcType in your FileTranslationList.
- * dstData is the buffer into which to resize and write the translated data.
- * dstType is the desired ScrapType of the translated file.
- * dstTypeHint is the hint that was paired with dstType in your FileTranslationList.
- *
- * A note about 'hints'. They are only hints. Your extension must be able to operate without
- * them or if they are incorrect.
- *
- * You can use all the standard toolbox routines to accomplish the translation.
- *
- * The first thing you should do is call SetTranslationAdvertisement. It will draw the progress
- * dialog window. The PicHandle parameter is a handle to the PICT that will be drawn in
- * in the top of the progress dialog. If it is NIL, no advertisment will be drawn, and the
- * dialog will be shrunk down to eliminate the blank space. Note, this shrinking will also
- * happen if you call UpdateTranslationProgress before SetTranslationAdvertisement. The
- * TranslationMgr will DisposeHandle the PICT when the translation is done. Therefore,
- * the PICT should be a non-purgable, non-resource handle. If you store it as a resource
- * in your Translation Extension, use OpenComponentResFile and DetachResource.
- *
- * You must periodically call the progress "call back" routine UpdateTranslationProgress.
- * You pass to it a number from one to one hundred that represents the chronological
- * percentage of the translation that has been completed.
- * The progress routine updates the progress status bar and handles the events a user can
- * do to cancel the translation. If the user does cancel, that fact is returned to you by the
- * progress routine. You should abort the translation, clean up anything you have allocated
- * and return userCancelErr.
- *
- ************************************************************************************************/
- pascal ComponentResult DoTranslateScrap(ComponentInstance self, TranslationRefNum progressRefNum,
- const void* srcDataPtr, Size srcDataLength, ScrapType srcType, long srcTypeHint,
- Handle dstData, ScrapType dstType, long dstTypeHint)
- {
- #pragma unused(self)
- #pragma unused(progressRefNum)
- #pragma unused(srcDataPtr)
- #pragma unused(srcDataLength)
- #pragma unused(srcType)
- #pragma unused(srcTypeHint)
- #pragma unused(dstData)
- #pragma unused(dstType)
- #pragma unused(dstTypeHint)
- return paramErr;
- }
-
-
-